﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ace_pso.Utility
{
    public class DataGenerator
    {
        #region paramters
        private int ages = 3;
        private int periods = 3;
        private int scenarios = 10;

        double[] v;
        double[,] demands;
        double[] u;
        double[] b;
        double[] c;
        double[] g;
        double[] h;
        double[] p;
        private int[, ,] m;

        #endregion

        Random random = new Random();

        public DataGenerator()
        {
            demands = new double[3, 10];

            //第一个计划期
            for (int i = 0; i < 5; i++)
            {
                demands[0, i] = 51;
                demands[0, i + 5] = 61;
            }

            //第二个计划期
            for (int i = 0; i < 3; i++)
            {
                demands[1, i] = 55;
                demands[1, i + 7] = 63;
            }
            for (int i = 0; i < 2; i++)
            {
                demands[1, i + 3] = 59;
                demands[1, i + 5] = 70;
            }

            //第三个计划期

            demands[2, 0] = 56;
            demands[2, 1] = 59;
            demands[2, 2] = 63;
            demands[2, 3] = 55;
            demands[2, 4] = 59;
            demands[2, 5] = 71;
            demands[2, 6] = 81;
            demands[2, 7] = 67;
            demands[2, 8] = 71;
            demands[2, 9] = 80;

        }

        public void CreateData()
        {
            string fileStr;
            fileStr = CreateDemand()
                + CreatePrice()
                      + CreateUnitActivityCost()
                      + CreateActivityCoefficient()
                      + CreateCapacity()
                      + CreatePurchaseCost()
                      + CreateInventory()
                      + CreateFixedCost()
                      + CreateScenarioMatrix()
                      + CreateProbablity();


            File.WriteAllText(Application.StartupPath + "\\data2.txt", fileStr);

        }

        private string CreateScenarioMatrix()
        {
            m = new int[periods, scenarios, scenarios];

            //第一个计划期

            for (int i = 0; i < scenarios; i++)
            {
                for (int j = 0; j < scenarios; j++)
                {
                    if ((i < 5 && j < 5) || (i >= 5 && j >= 5))
                    {
                        m[0, i, j] = 1;
                    }
                    else
                    {
                        m[0, i, j] = 0;
                    }
                }
            }
            //第二个计划期

            for (int i = 0; i < scenarios; i++)
            {
                for (int j = 0; j < scenarios; j++)
                {
                    if ((i < 3 && j < 3) || (i >= 3 && i < 5 && j >= 3 && j < 5) || (i >= 5 && i < 7 && j >= 5 && j < 7) || (i >= 7 && j >= 7))
                    {
                        m[1, i, j] = 1;
                    }
                    else
                    {
                        m[1, i, j] = 0;
                    }
                }
            }

            //第三个计划期
            for (int i = 0; i < scenarios; i++)
            {
                for (int j = 0; j < scenarios; j++)
                {

                    m[2, i, j] = 0;

                }
            }
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("m=");
            for (int i = 0; i < periods; i++)
            {
                for (int j = 0; j < scenarios; j++)
                {
                    for (int k = 0; k < scenarios; k++)
                    {
                        sb.Append(m[i, j, k] + " ");
                    }
                    sb.Append("\r\n");
                }
            }
            sb.AppendLine(";");


            return sb.ToString();
        }

        private string CreatePrice()
        {
            p = new double[periods];

            for (int i = 0; i < periods; i++)
            {
                p[i] = random.Next(120, 150);

            }

            //转化成字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("p=");
            for (int i = 0; i < periods; i++)
            {

                sb.Append((int)p[i] + " ");


            }
            sb.Append("\r\n");
            sb.AppendLine(";");

            return sb.ToString();
        }

        private string CreateProbablity()
        {
            double[] prob = new double[] { 0.036, 0.048, 0.036, 0.056, 0.224, 0.090, 0.210, 0.030, 0.150, 0.120 };

            StringBuilder sb = new StringBuilder();
            sb.AppendLine("prob=");

            for (int i = 0; i < scenarios; i++)
            {
                sb.Append(10000 * prob[i] + " ");
            }
            sb.Append("\r\n");
            // sb.AppendLine(";");

            return sb.ToString();
        }

        private string CreateDemand()
        {
            //转化成字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("d=");
            for (int i = 0; i < periods; i++)
            {
                for (int j = 0; j < scenarios; j++)
                {
                    sb.Append((int)demands[i, j] + " ");
                }
                sb.Append("\r\n");
            }
            sb.AppendLine(";");

            return sb.ToString();
        }

        /// <summary>
        /// 单位作业成本 u(i,l)
        /// </summary>
        private string CreateUnitActivityCost()
        {
            u = new double[ages];
            for (int i = 0; i < ages; i++)
            {
                u[i] = 10 + random.Next(10);

            }

            //转化成字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("u=");
            for (int i = 0; i < ages; i++)
            {
                sb.Append((int)u[i] + " ");

            }
            sb.Append("\r\n");
            sb.AppendLine(";");

            return sb.ToString();
        }
        /// <summary>
        /// 作业系数 v(i,mi,l)
        /// </summary>
        /// <param name="periods"></param>
        /// <returns></returns>
        private string CreateActivityCoefficient()
        {
            v = new double[ages];
            for (int i = 0; i < ages; i++)
            {

                v[i] = 4 + 2 * random.NextDouble();

            }
            //转化成字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("v=");
            for (int i = 0; i < ages; i++)
            {

                sb.Append((int)v[i] + " ");
            }
            sb.Append("\r\n");
            sb.AppendLine(";");
            return sb.ToString();
        }

        /// <summary>
        /// 容量 b(i,l)
        /// </summary>
        /// <param name="periods"></param>
        /// <returns></returns>
        private string CreateCapacity()
        {
            int b0 = 10000;//todo:可能设置的有点大

            b = new double[ages];
            b[0] = b0;
            for (int i = 1; i < ages; i++)
            {
                b[i] = b[i - 1] * (1 - 0.1 * random.NextDouble());
            }

            //转化成字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("b=");
            for (int i = 0; i < ages; i++)
            {
                sb.Append((int)b[i] + " ");

            }
            sb.Append("\r\n");
            sb.AppendLine(";");

            return sb.ToString();
        }

        /// <summary>
        /// 购买作业单元的变动成本 c(i,t)
        /// </summary>
        /// <param name="whichCase"></param>
        /// <param name="periods"></param>
        /// <returns></returns>
        private string CreatePurchaseCost()
        {
            int c0 = 100;


            c = new double[periods];
            c[0] = c0;

            for (int i = 1; i < periods; i++)
            {

                c[i] = c[i - 1] * (1 + 0.1 * random.NextDouble());

            }


            //转化成字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("c=");
            for (int i = 0; i < periods; i++)
            {

                sb.Append((int)c[i] + " ");

            }
            sb.Append("\r\n");

            sb.AppendLine(";");

            return sb.ToString();
        }

        private string CreateFixedCost()
        {
            int g0 = 200;

            g = new double[periods];
            g[0] = g0;
            for (int i = 1; i < periods; i++)
            {

                g[i] = g[i - 1] * (1 + 0.1 * random.NextDouble());

            }

            //转化成字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("g=");
            for (int i = 0; i < periods; i++)
            {


                sb.Append((int)g[i] + " ");

            }
            sb.Append("\r\n");

            sb.AppendLine(";");

            return sb.ToString();
        }

        /// <summary>
        /// 库存 h(i,mi,t)
        /// </summary>
        /// <param name="periods"></param>
        /// <returns></returns>
        private string CreateInventory()
        {
            h = new double[periods];
            for (int i = 0; i < periods; i++)
            {
                h[i] = u[i] * v[i] * 0.1 * (1 + 0.05 * random.NextDouble());
            }

            //转化成字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("h=");
            for (int i = 0; i < periods; i++)
            {

                sb.Append((int)h[i] + " ");
            }
            sb.Append("\r\n");

            sb.AppendLine(";");

            return sb.ToString();
        }
    }
}
